package edu.chl.dat255.bluebanana.data.impl;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import edu.chl.dat255.bluebanana.data.IStorage;

public class SQLiteStorage implements IStorage {

	private static final String TAG = "SQLiteAdapter";

	private DatabaseHelper mDbHelper;
	private SQLiteDatabase mDb;

	private static final String TABLE_COLUMNS = DbConst.KEY_NAME
			+ " text not null," + DbConst.KEY_ICON_PATH + " text not null,"
			+ DbConst.KEY_SCREEN_BRIGHTNESS + " integer not null,"
			+ DbConst.KEY_SCREEN_TIMEOUT + " integer not null,"
			+ DbConst.KEY_CALL_VOLUME + " integer not null,"
			+ DbConst.KEY_RINGER_MODE + " integer not null,"
			+ DbConst.KEY_NOTIFICATION_VOLUME + " integer not null,"
			+ DbConst.KEY_MUTE_ENABLE + " integer not null,"
			+ DbConst.KEY_RINGTONE_PATH + " integer not null,"
			+ DbConst.KEY_MESSAGETONE_PATH + " integer not null,"
			+ DbConst.KEY_WIFI_ENABLE + " integer not null,"
			+ DbConst.KEY_BLUETOOTH_ENABLE + " integer not null,"
			+ DbConst.KEY_PACKET_DATA_ENABLE + " integer not null,"
			+ DbConst.KEY_FLIGHT_MODE_ENABLE + " integer not null,"
			+ DbConst.KEY_AUTO_MESSAGE_ENABLE + " integer not null,"
			+ DbConst.KEY_AUTO_MESSAGE_CONTENT + " text not null,"
			+ DbConst.KEY_BLOCKED_CALLS + " integer not null,"
			+ DbConst.KEY_VIBRATE_ENABLE + " integer not null,"
			+ DbConst.KEY_SCREEN_AUTO_BRIGHTNESS_ENABLE + " integer not null"
			+ ");";
	
	private static final String[] columnNames = {
		DbConst.KEY_ROWID, DbConst.KEY_NAME, DbConst.KEY_ICON_PATH,
		DbConst.KEY_SCREEN_BRIGHTNESS, DbConst.KEY_SCREEN_TIMEOUT,
		DbConst.KEY_CALL_VOLUME, DbConst.KEY_RINGER_MODE,
		DbConst.KEY_NOTIFICATION_VOLUME, DbConst.KEY_MUTE_ENABLE,
		DbConst.KEY_RINGTONE_PATH, DbConst.KEY_MESSAGETONE_PATH,
		DbConst.KEY_WIFI_ENABLE, DbConst.KEY_BLUETOOTH_ENABLE,
		DbConst.KEY_PACKET_DATA_ENABLE, DbConst.KEY_FLIGHT_MODE_ENABLE,
		DbConst.KEY_AUTO_MESSAGE_ENABLE,
		DbConst.KEY_AUTO_MESSAGE_CONTENT, DbConst.KEY_BLOCKED_CALLS,
		DbConst.KEY_VIBRATE_ENABLE,
		DbConst.KEY_SCREEN_AUTO_BRIGHTNESS_ENABLE };

	private static final String USER_PROFILES_TABLE_CREATE = "create table "
			+ DbConst.USER_PROFILES_TABLE + " (" + DbConst.KEY_ROWID
			+ " integer primary key autoincrement, " + TABLE_COLUMNS;

	private static final String DEFAULT_PROFILES_TABLE_CREATE = "create table "
			+ DbConst.DEFAULT_PROFILES_TABLE + " (" + DbConst.KEY_ROWID
			+ " integer primary key autoincrement, " + TABLE_COLUMNS;

	private static final String SYSTEM_SETTINGS_TABLE_CREATE = "create table "
			+ DbConst.SYSTEM_SETTINGS_TABLE + " (" + DbConst.KEY_ROWID
			+ " integer primary key autoincrement, " + TABLE_COLUMNS;

	private final Context mCtx;

	private static class DatabaseHelper extends SQLiteOpenHelper {

		DatabaseHelper(Context context) {
			super(context, DbConst.DATABASE_NAME, null,
					DbConst.DATABASE_VERSION);
		}

		@Override
		public void onCreate(SQLiteDatabase db) {
			db.execSQL(USER_PROFILES_TABLE_CREATE);
			db.execSQL(DEFAULT_PROFILES_TABLE_CREATE);
			db.execSQL(SYSTEM_SETTINGS_TABLE_CREATE);
		}

		@Override
		public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
			Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
					+ newVersion + ", which will destroy all old data");
			db.execSQL("DROP TABLE IF EXISTS notes");
			onCreate(db);
		}
	}

	public SQLiteStorage(Context ctx) {
		this.mCtx = ctx;
	}
	/**
	 * Opens the databse
	 * @return The database
	 * @throws SQLException
	 */
	public SQLiteStorage open() throws SQLException {
		mDbHelper = new DatabaseHelper(mCtx);
		mDb = mDbHelper.getWritableDatabase();

		return this;
	}
	/**
	 * Closes the database
	 */
	public void close() {
		mDbHelper.close();
	}

	@Override
	/**
	 * @inheritDoc
	 */
	public Cursor getAllUserProfiles() {
		Cursor c = mDb.query(DbConst.USER_PROFILES_TABLE, columnNames, null, null, null,
				null, null);

		return c;
	}

	@Override
	/**
	 * @inheritDoc
	 */
	public Cursor getAllDefaultProfiles() {
		Cursor c = mDb.query(DbConst.DEFAULT_PROFILES_TABLE, columnNames, null, null, null,
				null, null);

		return c;
	}

	@Override
	/**
	 * @inheritDoc
	 */
	public Cursor getCurrentSystemProfile() {
		Cursor c = mDb.query(DbConst.SYSTEM_SETTINGS_TABLE, columnNames, null, null, null,
				null, null);

		return c;
	}

	@Override
	/**
	 * @inheritDoc
	 */
	public Cursor getProfile(long id) {
		Cursor c = mDb.query(true, DbConst.USER_PROFILES_TABLE, columnNames, DbConst.KEY_ROWID
				+ "=" + id, null, null, null, null, null);

		if (c != null) {
			c.moveToFirst();
		}

		return c;
	}

	@Override
	/**
	 * @inheritDoc
	 */
	public long addProfile() {
		ContentValues values = new ContentValues();
		values.put(DbConst.KEY_NAME, "New Profile");
		values.put(DbConst.KEY_ICON_PATH, "null");
		values.put(DbConst.KEY_SCREEN_BRIGHTNESS, 100);
		values.put(DbConst.KEY_SCREEN_TIMEOUT, 30);
		values.put(DbConst.KEY_CALL_VOLUME, 100);
		values.put(DbConst.KEY_RINGER_MODE,
				android.media.AudioManager.RINGER_MODE_NORMAL);
		values.put(DbConst.KEY_NOTIFICATION_VOLUME, 100);
		values.put(DbConst.KEY_MUTE_ENABLE, false);
		values.put(DbConst.KEY_RINGTONE_PATH, "null");
		values.put(DbConst.KEY_MESSAGETONE_PATH, "null");
		values.put(DbConst.KEY_WIFI_ENABLE, false);
		values.put(DbConst.KEY_BLUETOOTH_ENABLE, false);
		values.put(DbConst.KEY_PACKET_DATA_ENABLE, true);
		values.put(DbConst.KEY_FLIGHT_MODE_ENABLE, false);
		values.put(DbConst.KEY_AUTO_MESSAGE_ENABLE, false);
		values.put(DbConst.KEY_AUTO_MESSAGE_CONTENT,
				"Sorry, I am not availible right now. Calling you back in 5!");
		values.put(DbConst.KEY_BLOCKED_CALLS, "New Profile");
		values.put(DbConst.KEY_VIBRATE_ENABLE, false);
		values.put(DbConst.KEY_SCREEN_AUTO_BRIGHTNESS_ENABLE, "false");
		return mDb.insert(DbConst.USER_PROFILES_TABLE, null, values);
	}

	@Override
	/**
	 * @inheritDoc
	 */
	public void deleteProfile(long id) {
		mDb.delete(DbConst.USER_PROFILES_TABLE, DbConst.KEY_ROWID + "=" + id,
				null);
	}

	@Override
	/**
	 * @inheritDoc
	 */
	public void deleteAllProfiles() {
		mDb.delete(DbConst.USER_PROFILES_TABLE, null, null);
	}

	@Override
	/**
	 * @inheritDoc
	 */
	public void updateValue(long id, String dbconstant, String value) {
		ContentValues values = new ContentValues();
		values.put(dbconstant, value);
		mDb.update(DbConst.USER_PROFILES_TABLE, values, DbConst.KEY_ROWID + "="
				+ id, null);
	}

	@Override
	/**
	 * @inheritDoc
	 */
	public void updateValue(long id, String dbconstant, int value) {
		ContentValues values = new ContentValues();
		values.put(dbconstant, value);
		mDb.update(DbConst.USER_PROFILES_TABLE, values, DbConst.KEY_ROWID + "="
				+ id, null);
	}

	@Override
	/**
	 * @inheritDoc
	 */
	public void updateValue(long id, String dbconstant, boolean value) {
		ContentValues values = new ContentValues();
		int valueAsInt = 0;
		if (value)
			valueAsInt = 1;

		values.put(dbconstant, valueAsInt);
		mDb.update(DbConst.USER_PROFILES_TABLE, values, DbConst.KEY_ROWID + "="
				+ id, null);
	}
	
	@Override
	/**
	 * @inheritDoc
	 */
	public void updateSystemSettingValue(long id, String dbconstant, String value) {
		ContentValues values = new ContentValues();
		values.put(dbconstant, value);
		mDb.update(DbConst.SYSTEM_SETTINGS_TABLE, values, DbConst.KEY_ROWID + "="
				+ id, null);
	}

	@Override
	/**
	 * @inheritDoc
	 */
	public void updateSystemSettingValue(long id, String dbconstant, int value) {
		ContentValues values = new ContentValues();
		values.put(dbconstant, value);
		mDb.update(DbConst.SYSTEM_SETTINGS_TABLE, values, DbConst.KEY_ROWID + "="
				+ id, null);
	}

	@Override
	/**
	 * @inheritDoc
	 */
	public void updateSystemSettingValue(long id, String dbconstant, boolean value) {
		ContentValues values = new ContentValues();
		int valueAsInt = 0;
		if (value)
			valueAsInt = 1;

		values.put(dbconstant, valueAsInt);
		mDb.update(DbConst.SYSTEM_SETTINGS_TABLE, values, DbConst.KEY_ROWID + "="
				+ id, null);
	}

	@Override
	/**
	 * @inheritDoc
	 */
	public String getTextValue(long id, String dbconstant) {
		Cursor c = mDb.query(true, DbConst.USER_PROFILES_TABLE, new String[] {
				DbConst.KEY_ROWID, dbconstant, }, DbConst.KEY_ROWID + "=" + id,
				null, null, null, null, null);

		c.moveToFirst();
		String returnValue = c.getString(c.getColumnIndexOrThrow(dbconstant));
		c.close();
		return returnValue;
	}

	@Override
	/**
	 * @inheritDoc
	 */
	public int getIntValue(long id, String dbconstant) {
		Cursor c = mDb.query(true, DbConst.USER_PROFILES_TABLE, new String[] {
				DbConst.KEY_ROWID, dbconstant, }, DbConst.KEY_ROWID + "=" + id,
				null, null, null, null, null);

		c.moveToFirst();
		int returnValue = c.getInt(c.getColumnIndexOrThrow(dbconstant));
		c.close();
		return returnValue;
	}

	@Override
	/**
	 * @inheritDoc
	 */
	public boolean getBooleanValue(long id, String dbconstant) {
		Cursor c = mDb.query(true, DbConst.USER_PROFILES_TABLE, new String[] {
				DbConst.KEY_ROWID, dbconstant, }, DbConst.KEY_ROWID + "=" + id,
				null, null, null, null, null);

		c.moveToFirst();
		boolean returnValue = (c.getInt(c.getColumnIndexOrThrow(dbconstant)) == 1);
		c.close();
		return returnValue;
	}

	@Override
	/**
	 * @inheritDoc
	 */
	public void insertDefaultProfiles() {
		Cursor cur = mDb.rawQuery("SELECT count(*) FROM "
				+ DbConst.DEFAULT_PROFILES_TABLE, null);
		if (cur != null) {
			cur.moveToFirst(); // Always one row returned.
			if (cur.getInt(0) == 0) { // Zero count means empty table.
				addDefaultProfilesToDb();
			}
		}

		mDb.execSQL("INSERT INTO " + DbConst.USER_PROFILES_TABLE
				+ " SELECT * FROM " + DbConst.DEFAULT_PROFILES_TABLE);
	}

	private void addDefaultProfilesToDb() {
		ContentValues values = new ContentValues();
		values.put(DbConst.KEY_NAME, "Default profile 1");
		values.put(DbConst.KEY_ICON_PATH, "null");
		values.put(DbConst.KEY_SCREEN_BRIGHTNESS, 100);
		values.put(DbConst.KEY_SCREEN_TIMEOUT, 30);
		values.put(DbConst.KEY_CALL_VOLUME, 100);
		values.put(DbConst.KEY_RINGER_MODE,
				android.media.AudioManager.RINGER_MODE_NORMAL);
		values.put(DbConst.KEY_NOTIFICATION_VOLUME, 100);
		values.put(DbConst.KEY_MUTE_ENABLE, false);
		values.put(DbConst.KEY_RINGTONE_PATH, "null");
		values.put(DbConst.KEY_MESSAGETONE_PATH, "null");
		values.put(DbConst.KEY_WIFI_ENABLE, false);
		values.put(DbConst.KEY_BLUETOOTH_ENABLE, false);
		values.put(DbConst.KEY_PACKET_DATA_ENABLE, true);
		values.put(DbConst.KEY_FLIGHT_MODE_ENABLE, false);
		values.put(DbConst.KEY_AUTO_MESSAGE_ENABLE, false);
		values.put(DbConst.KEY_AUTO_MESSAGE_CONTENT,
				"Sorry, I am not availible right now. Calling you back in 5!");
		values.put(DbConst.KEY_BLOCKED_CALLS, "New Profile");
		values.put(DbConst.KEY_VIBRATE_ENABLE, false);
		values.put(DbConst.KEY_SCREEN_AUTO_BRIGHTNESS_ENABLE, "false");
		mDb.insert(DbConst.DEFAULT_PROFILES_TABLE, null, values);

		values = new ContentValues();
		values.put(DbConst.KEY_NAME, "Default profile 2");
		values.put(DbConst.KEY_ICON_PATH, "null");
		values.put(DbConst.KEY_SCREEN_BRIGHTNESS, 100);
		values.put(DbConst.KEY_SCREEN_TIMEOUT, 30);
		values.put(DbConst.KEY_CALL_VOLUME, 100);
		values.put(DbConst.KEY_RINGER_MODE,
				android.media.AudioManager.RINGER_MODE_NORMAL);
		values.put(DbConst.KEY_NOTIFICATION_VOLUME, 100);
		values.put(DbConst.KEY_MUTE_ENABLE, false);
		values.put(DbConst.KEY_RINGTONE_PATH, "null");
		values.put(DbConst.KEY_MESSAGETONE_PATH, "null");
		values.put(DbConst.KEY_WIFI_ENABLE, false);
		values.put(DbConst.KEY_BLUETOOTH_ENABLE, false);
		values.put(DbConst.KEY_PACKET_DATA_ENABLE, true);
		values.put(DbConst.KEY_FLIGHT_MODE_ENABLE, false);
		values.put(DbConst.KEY_AUTO_MESSAGE_ENABLE, false);
		values.put(DbConst.KEY_AUTO_MESSAGE_CONTENT,
				"Sorry, I am not availible right now. Calling you back in 5!");
		values.put(DbConst.KEY_BLOCKED_CALLS, "New Profile");
		values.put(DbConst.KEY_VIBRATE_ENABLE, false);
		values.put(DbConst.KEY_SCREEN_AUTO_BRIGHTNESS_ENABLE, "false");
		mDb.insert(DbConst.DEFAULT_PROFILES_TABLE, null, values);

		values = new ContentValues();
		values.put(DbConst.KEY_NAME, "Default profile 3");
		values.put(DbConst.KEY_ICON_PATH, "null");
		values.put(DbConst.KEY_SCREEN_BRIGHTNESS, 100);
		values.put(DbConst.KEY_SCREEN_TIMEOUT, 30);
		values.put(DbConst.KEY_CALL_VOLUME, 100);
		values.put(DbConst.KEY_RINGER_MODE,
				android.media.AudioManager.RINGER_MODE_NORMAL);
		values.put(DbConst.KEY_NOTIFICATION_VOLUME, 100);
		values.put(DbConst.KEY_MUTE_ENABLE, false);
		values.put(DbConst.KEY_RINGTONE_PATH, "null");
		values.put(DbConst.KEY_MESSAGETONE_PATH, "null");
		values.put(DbConst.KEY_WIFI_ENABLE, false);
		values.put(DbConst.KEY_BLUETOOTH_ENABLE, false);
		values.put(DbConst.KEY_PACKET_DATA_ENABLE, true);
		values.put(DbConst.KEY_FLIGHT_MODE_ENABLE, false);
		values.put(DbConst.KEY_AUTO_MESSAGE_ENABLE, false);
		values.put(DbConst.KEY_AUTO_MESSAGE_CONTENT,
				"Sorry, I am not availible right now. Calling you back in 5!");
		values.put(DbConst.KEY_BLOCKED_CALLS, "New Profile");
		values.put(DbConst.KEY_VIBRATE_ENABLE, false);
		values.put(DbConst.KEY_SCREEN_AUTO_BRIGHTNESS_ENABLE, "false");
		mDb.insert(DbConst.DEFAULT_PROFILES_TABLE, null, values);
	}

	@Override
	/**
	 * @inheritDoc
	 */
	public long createSystemSettingsProfile() {
		ContentValues values = new ContentValues();
		values.put(DbConst.KEY_NAME, "New Profile");
		values.put(DbConst.KEY_ICON_PATH, "null");
		values.put(DbConst.KEY_SCREEN_BRIGHTNESS, 100);
		values.put(DbConst.KEY_SCREEN_TIMEOUT, 30);
		values.put(DbConst.KEY_CALL_VOLUME, 100);
		values.put(DbConst.KEY_RINGER_MODE,
				android.media.AudioManager.RINGER_MODE_NORMAL);
		values.put(DbConst.KEY_NOTIFICATION_VOLUME, 100);
		values.put(DbConst.KEY_MUTE_ENABLE, false);
		values.put(DbConst.KEY_RINGTONE_PATH, "null");
		values.put(DbConst.KEY_MESSAGETONE_PATH, "null");
		values.put(DbConst.KEY_WIFI_ENABLE, false);
		values.put(DbConst.KEY_BLUETOOTH_ENABLE, false);
		values.put(DbConst.KEY_PACKET_DATA_ENABLE, true);
		values.put(DbConst.KEY_FLIGHT_MODE_ENABLE, false);
		values.put(DbConst.KEY_AUTO_MESSAGE_ENABLE, false);
		values.put(DbConst.KEY_AUTO_MESSAGE_CONTENT,
				"Sorry, I am not availible right now. Calling you back in 5!");
		values.put(DbConst.KEY_BLOCKED_CALLS, "New Profile");
		values.put(DbConst.KEY_VIBRATE_ENABLE, false);
		values.put(DbConst.KEY_SCREEN_AUTO_BRIGHTNESS_ENABLE, "false");
		return mDb.insert(DbConst.SYSTEM_SETTINGS_TABLE, null, values);
	}

}
